﻿using Grpc.Core;
using Grpc.Core.Interceptors;
using MX.Core.Log;
using MX.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UserCenter.Api.CallContexts;
using UserCenter.Api.Tools;
using UserCenter.BLL;

namespace UserCenter.Api.Interceptors
{
    public abstract class BaseMerchantInterceptor<T> : Interceptor where T : BaseMerchantContext
    {
        const int ECH = 0x9;

        ILogger logger = Logger.GetLogger("BaseMerchantInterceptor");



        public override Task<TResponse> UnaryServerHandler<TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod<TRequest, TResponse> continuation)
        {
            try
            {
                var cxt = Activator.CreateInstance(typeof(T), new object[] { context }) as T;
                cxt.MerchantId = Utils.CheckMerchantHeader(context, (merId) =>
                {
                    var merchant = MerchantBLL.Info(merId);
                    if (merchant != null)
                    {
                        return merchant.SignKey;
                    }
                    else
                    {
                        context.Throw(ECH, 0x9);
                        return null;
                    }
                });
                var reponse = continuation(request, cxt);
                return reponse;
            }
            catch (RpcException ex)
            {
                var errorEntry = context.ResponseTrailers.Where(t => t.Key.Equals("error")).SingleOrDefault();
                if (errorEntry != null)
                {

                    try
                    {
                        var error = ErrorMessage.Parser.ParseFrom(Convert.FromBase64String(errorEntry.Value));
                        logger.Error(new Exception($"[{error.Code}]{error.Message}", innerException: ex), "GRPC错误");
                    }
                    catch (Exception ex2)
                    {
                        logger.Error(ex2, "GRPC错误解析失败"); 
                    }
                }
                else
                {
                    logger.Error(ex, "");
                }

                throw ex;
            }
            catch (Exception ex)
            {
                logger.Error(ex, "");
                //服务器异常稍后重试
                context.Throw(ECH, 88);
                return null;
            }


        }
    }
}
